package com.example.controller;

import com.example.entity.Lecture;
import com.example.entity.example.*;
import com.example.entity.vo.LectureVO;
import com.example.service.*;
import com.example.util.CustomConstant;
import com.example.util.CustomUtil;
import com.example.util.RedisUtil;
import com.example.util.ResultEntity;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Controller
public class CommonController {
    @Bean
    public BCryptPasswordEncoder getPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    UserService userService;

    @Autowired
    StudentService studentService;

    @Autowired
    TeacherService teacherService;

    @Autowired
    DepartmentService departmentService;

    @Autowired
    CourseService courseService;

    @Autowired
    LectureService lectureService;

    @Autowired
    LectureController lectureController;

    @RequestMapping("/get/verify/code")
    public void getVerifyCode(HttpServletResponse response, HttpSession session) throws IOException {
        int width = 120;
        int height = 40;
        Random ran = new Random();

        // 设置response头信息
        // 禁止缓存
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        // 生成缓冲区image类
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 美化图片
        Graphics g = image.getGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);

        char[] ch = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
                't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
                'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8',
                '9'};

        StringBuilder code = new StringBuilder();

        for (int i = 0; i < 4; i++) {
            int index = ran.nextInt(62);
            code.append(ch[index]);
            g.setColor(CustomUtil.randomColor(ran));
            g.setFont(CustomUtil.randomFont(ran));
            g.drawString(ch[index] + "", width * i / 5 + 20, height / 2 + 10);
        }

        // 保存到session域
        session.setAttribute("verifyCode", code.toString());

        // 画干扰线
        for (int i = 0; i < 6; i++) {
            g.setColor(CustomUtil.randomColor(ran));
            int x1 = ran.nextInt(width);
            int x2 = ran.nextInt(width);
            int y1 = ran.nextInt(height);
            int y2 = ran.nextInt(height);
            g.drawLine(x1, y1, x2, y2);
        }

        // 画干扰点
        for (int i = 0; i < 10; i++) {
            g.setColor(CustomUtil.randomColor(ran));
            int x = ran.nextInt(width);
            int y = ran.nextInt(height);
            g.drawOval(x, y, 2, 2);
        }

        ImageIO.write(image, "JPEG", response.getOutputStream());
        response.getOutputStream().flush();
    }

    @ResponseBody
    @RequestMapping("/send/message/verify/code")
    public ResultEntity<Object> sendMessageVerifyCode(@RequestParam("phone") String phone, HttpServletRequest request) {
        // 判断用户是否频繁发送
        String ip = CustomUtil.getIp(request);
        String key = CustomConstant.REDIS_VERIFY_CODE_PREFIX + ip;
        if (redisUtil.get(key) != null) {
            long cd = redisUtil.getExpire(key);
            return ResultEntity.failedWithoutData(cd + "s后可再次发送");
        }
        redisUtil.set(key, "", 60, TimeUnit.SECONDS);

        // 发送验证码
        ResultEntity<String> resultEntity = CustomUtil.sendShortMessage(phone, 10);
        if (resultEntity.getCode() != 0) {
            return ResultEntity.failedWithoutData(resultEntity.getMsg());
        }
        String verifyCode = resultEntity.getData();
        redisUtil.set(CustomConstant.REDIS_VERIFY_CODE_PREFIX + phone, verifyCode, 10, TimeUnit.MINUTES);
        return ResultEntity.successWithoutData();
    }

    @RequestMapping("/welcome.html")
    public String welcomePage(ModelMap modelMap) {
        long userCount = userService.getCountByExample(new UserExample());
        long studentCount = studentService.getCountByExample(new StudentExample());
        long teacherCount = teacherService.getCountByExample(new TeacherExample());
        long departmentCount = departmentService.getCountByExample(new DepartmentExample());
        long courseCount = courseService.getCountByExample(new CourseExample());

        Object val = redisUtil.get(CustomConstant.REDIS_ONLINE_COUNT);
        String onlineCount = val == null ? "error" : val.toString();
        modelMap.addAttribute("userCount", userCount);
        modelMap.addAttribute("studentCount", studentCount);
        modelMap.addAttribute("teacherCount", teacherCount);
        modelMap.addAttribute("departmentCount", departmentCount);
        modelMap.addAttribute("courseCount", courseCount);
        modelMap.addAttribute("onlineCount", onlineCount);

        // 获取之后10条授课数据
        List<Lecture> lectureList = lectureService.getOrderByDateWithLimit(new Date(), 5);
        List<LectureVO> lectureVOList = new ArrayList<>(lectureList.size());
        for (Lecture lecture : lectureList) {
            LectureVO lectureVO = lectureController.transformToLectureVO(lecture);
            lectureVOList.add(lectureVO);
        }
        modelMap.addAttribute("lectureVOList", lectureVOList);

        // 最近一条通知
        LectureVO lectureVO = lectureVOList == null || lectureVOList.isEmpty() ? null : lectureVOList.get(0);
        String message;
        if (lectureVO == null) {
            message = "没有最新课程";
        } else {
            String teacherName = lectureVO.getTeacherName();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM-dd HH:mm");
            String courseDate = simpleDateFormat.format(lectureVO.getDate());
            String courseName = lectureVO.getCourseName();
            message = "请注意！" + teacherName + "老师将在 " + courseDate + " 授课《" + courseName + "》";
        }
        modelMap.addAttribute("message", message);

        return "welcome";
    }
}
